home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / find_names.c < prev    next >
C/C++ Source or Header  |  1992-04-10  |  6KB  |  273 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.3 kit.
  7.  * 
  8.  * Find Names
  9.  * 
  10.  * Finds all the pertinent file names, both from the administration and from the
  11.  * repository
  12.  * 
  13.  * Find Dirs
  14.  * 
  15.  * Finds all pertinent sub-directories of the checked out instantiation and the
  16.  * repository (and optionally the attic)
  17.  */
  18.  
  19. #include "cvs.h"
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "@(#)find_names.c 1.38 92/04/10";
  23. #endif
  24.  
  25. #if __STDC__
  26. static int find_dirs (char *dir, List * list, int checkadm);
  27. static int find_rcs (char *dir, List * list);
  28. #else
  29. static int find_rcs ();
  30. static int find_dirs ();
  31. #endif                /* __STDC__ */
  32.  
  33. static List *filelist;
  34.  
  35. /*
  36.  * add the key from entry on entries list to the files list
  37.  */
  38. static int
  39. add_entries_proc (node)
  40.     Node *node;
  41. {
  42.     Node *fnode;
  43.  
  44.     fnode = getnode ();
  45.     fnode->type = FILES;
  46.     fnode->key = xstrdup (node->key);
  47.     if (addnode (filelist, fnode) != 0)
  48.     freenode (fnode);
  49.     return (0);
  50. }
  51.  
  52. /*
  53.  * compare two files list node (for sort)
  54.  */
  55. static int
  56. fsortcmp (p, q)
  57.     Node *p, *q;
  58. {
  59.     return (strcmp (p->key, q->key));
  60. }
  61.  
  62. List *
  63. Find_Names (repository, which, aflag, optentries)
  64.     char *repository;
  65.     int which;
  66.     int aflag;
  67.     List **optentries;
  68. {
  69.     List *entries;
  70.     List *files;
  71.     char dir[PATH_MAX];
  72.  
  73.     /* make a list for the files */
  74.     files = filelist = getlist ();
  75.  
  76.     /* look at entries (if necessary) */
  77.     if (which & W_LOCAL)
  78.     {
  79.     /* parse the entries file (if it exists) */
  80.     entries = ParseEntries (aflag);
  81.  
  82.     if (entries != NULL)
  83.     {
  84.         /* walk the entries file adding elements to the files list */
  85.         (void) walklist (entries, add_entries_proc);
  86.  
  87.         /* if our caller wanted the entries list, return it; else free it */
  88.         if (optentries != NULL)
  89.         *optentries = entries;
  90.         else
  91.         dellist (&entries);
  92.     }
  93.     }
  94.  
  95.     if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT))
  96.     {
  97.     /* search the repository */
  98.     if (find_rcs (repository, files) != 0)
  99.         error (1, errno, "cannot open directory %s", repository);
  100.  
  101.     /* search the attic too */
  102.     if (which & W_ATTIC)
  103.     {
  104.         (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
  105.         (void) find_rcs (dir, files);
  106.     }
  107.     }
  108.  
  109.     /* sort the list into alphabetical order and return it */
  110.     sortlist (files, fsortcmp);
  111.     return (files);
  112. }
  113.  
  114. /*
  115.  * create a list of directories to traverse from the current directory
  116.  */
  117. List *
  118. Find_Dirs (repository, which)
  119.     char *repository;
  120.     int which;
  121. {
  122.     List *dirlist;
  123.  
  124.     /* make a list for the directories */
  125.     dirlist = getlist ();
  126.  
  127.     /* find the local ones */
  128.     if (which & W_LOCAL)
  129.     {
  130.     /* look only for CVS controlled sub-directories */
  131.     if (find_dirs (".", dirlist, 1) != 0)
  132.         error (1, errno, "cannot open current directory");
  133.     }
  134.  
  135.     /* look for sub-dirs in the repository */
  136.     if ((which & W_REPOS) && repository)
  137.     {
  138.     /* search the repository */
  139.     if (find_dirs (repository, dirlist, 0) != 0)
  140.         error (1, errno, "cannot open directory %s", repository);
  141.  
  142. #ifdef ATTIC_DIR_SUPPORT        /* XXX - FIXME */
  143.     /* search the attic too */
  144.     if (which & W_ATTIC)
  145.     {
  146.         char dir[PATH_MAX];
  147.  
  148.         (void) sprintf (dir, "%s/%s", repository, CVSATTIC);
  149.         (void) find_dirs (dir, dirlist, 0);
  150.     }
  151. #endif
  152.     }
  153.  
  154.     /* sort the list into alphabetical order and return it */
  155.     sortlist (dirlist, fsortcmp);
  156.     return (dirlist);
  157. }
  158.  
  159. /*
  160.  * Finds all the ,v files in the argument directory, and adds them to the
  161.  * files list.  Returns 0 for success and non-zero if the argument directory
  162.  * cannot be opened.
  163.  */
  164. static int
  165. find_rcs (dir, list)
  166.     char *dir;
  167.     List *list;
  168. {
  169.     Node *p;
  170.     CONST char *regex_err;
  171.     char line[50];
  172.     struct direct *dp;
  173.     DIR *dirp;
  174.  
  175.     /* set up to read the dir */
  176.     if ((dirp = opendir (dir)) == NULL)
  177.     return (1);
  178.  
  179.     /* set up a regular expression to find the ,v files */
  180.     (void) sprintf (line, ".*%s$", RCSEXT);
  181.     if ((regex_err = re_comp (line)) != NULL)
  182.     error (1, 0, "%s", regex_err);
  183.  
  184.     /* read the dir, grabbing the ,v files */
  185.     while ((dp = readdir (dirp)) != NULL)
  186.     {
  187.     if (re_exec (dp->d_name))
  188.     {
  189.         char *comma;
  190.  
  191.         comma = rindex (dp->d_name, ',');    /* strip the ,v */
  192.         *comma = '\0';
  193.         p = getnode ();
  194.         p->type = FILES;
  195.         p->key = xstrdup (dp->d_name);
  196.         if (addnode (list, p) != 0)
  197.         freenode (p);
  198.     }
  199.     }
  200.     (void) closedir (dirp);
  201.     return (0);
  202. }
  203.  
  204. /*
  205.  * Finds all the subdirectories of the argument dir and adds them to the
  206.  * specified list.  Sub-directories without a CVS administration directory
  207.  * are optionally ignored  Returns 0 for success or 1 on error.
  208.  */
  209. static int
  210. find_dirs (dir, list, checkadm)
  211.     char *dir;
  212.     List *list;
  213.     int checkadm;
  214. {
  215.     Node *p;
  216.     CONST char *regex_err;
  217.     char tmp[PATH_MAX];
  218.     char admdir[PATH_MAX];
  219.     struct direct *dp;
  220.     DIR *dirp;
  221.  
  222.     /* build a regex to blow off ,v files */
  223.     (void) sprintf (tmp, ".*%s$", RCSEXT);
  224.     if ((regex_err = re_comp (tmp)) != NULL)
  225.     error (1, 0, "%s", regex_err);
  226.  
  227.     /* set up to read the dir */
  228.     if ((dirp = opendir (dir)) == NULL)
  229.     return (1);
  230.  
  231.     /* read the dir, grabbing sub-dirs */
  232.     while ((dp = readdir (dirp)) != NULL)
  233.     {
  234.     if (strcmp (dp->d_name, ".") == 0 ||
  235.         strcmp (dp->d_name, "..") == 0 ||
  236.         strcmp (dp->d_name, CVSATTIC) == 0 ||
  237.         strcmp (dp->d_name, CVSLCK) == 0 ||
  238.         re_exec (dp->d_name))    /* don't bother stating ,v files */
  239.         continue;
  240.  
  241.     (void) sprintf (tmp, "%s/%s", dir, dp->d_name);
  242.     if (isdir (tmp))
  243.     {
  244.         /* check for administration directories (if needed) */
  245.         if (checkadm)
  246.         {
  247.         /* blow off symbolic links to dirs in local dir */
  248.         if (islink (tmp))
  249.             continue;
  250.  
  251.         /* check for new style */
  252.         (void) sprintf (admdir, "%s/%s", tmp, CVSADM);
  253.         if (!isdir (admdir))
  254.         {
  255.             /* and old style */
  256.             (void) sprintf (admdir, "%s/%s", tmp, OCVSADM);
  257.             if (!isdir (admdir))
  258.             continue;
  259.         }
  260.         }
  261.  
  262.         /* put it in the list */
  263.         p = getnode ();
  264.         p->type = DIRS;
  265.         p->key = xstrdup (dp->d_name);
  266.         if (addnode (list, p) != 0)
  267.         freenode (p);
  268.     }
  269.     }
  270.     (void) closedir (dirp);
  271.     return (0);
  272. }
  273.